package org.xxl.utils 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.getTimer;
	import org.osflash.signals.ISignal;
	import org.osflash.signals.natives.sets.DisplayObjectSignalSet;
	import org.osflash.signals.Signal;
	/**
	 * ...
	 * @author XXL
	 */
	public class GameTimer 
	{
		private static const ONE_SECOND:int = 1000;
		
		private static var _INSTANCE:GameTimer = null;
		
		public static function GetInstance():GameTimer
		{
			if (_INSTANCE == null)
			{
				_INSTANCE = new GameTimer();
			}
			return _INSTANCE;
		}
		
		private const enterFrameDispatcher:Sprite = new Sprite();
		private var signalSet:DisplayObjectSignalSet;
		private var prevTime:int;
		
		private var _tickSignal:ISignal;
		private var _frameSignal:ISignal;
		private var _secondSignal:ISignal;
		
		private var interval:int = 0;
		private var f_interval:int = 0;
		private var s_interval:int = 0;
		
		/**
		 * 一帧需要消耗的时间(毫秒),25帧/秒 = 1000毫秒 / 40;
		 */
		public var frameInterval:int = 40;
		
		public function GameTimer() 
		{
			if (_INSTANCE)
			{
				throw new Error("GameTimer只能是唯一的");
			}
			_INSTANCE = this;
			
			_tickSignal = new Signal(int);
			_frameSignal = new Signal(int);
			_secondSignal = new Signal(int);
			prevTime = getTimer();
			signalSet = new DisplayObjectSignalSet(enterFrameDispatcher);
			signalSet.enterFrame.add(tick);
		}
		
		private function tick(e:Event):void
		{
			var nowTime:int = getTimer();
			interval = nowTime - prevTime;
			nowTime = prevTime;
			
			f_interval += interval;
			s_interval += interval;
			
			_tickSignal.dispatch(interval);
			
			if (f_interval >= frameInterval)
			{
				f_interval -= frameInterval;
				_frameSignal.dispatch(frameInterval);
			}
			if (s_interval >= ONE_SECOND)
			{
				s_interval -= ONE_SECOND;
				_secondSignal.dispatch(ONE_SECOND);
			}
		}
		
		public function get tickSignal():ISignal 
		{
			return _tickSignal;
		}
		
		public function get frameSignal():ISignal 
		{
			return _frameSignal;
		}
		
		public function get secondSignal():ISignal 
		{
			return _secondSignal;
		}
		
	}

}